package com.iretailer.report.auth;

import cn.hutool.json.JSONUtil;
import com.iretailer.report.common.InternationalMessage;
import com.iretailer.report.util.RMap;
import com.iretailer.report.util.SecurityUserUtil;
import com.iretailer.report.util.SpringUtils;
import com.xkcoding.justauth.AuthRequestFactory;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 企业版微信登录
 *
 * @author : Bennie
 **/
@Slf4j
@RestController
@RequestMapping("/oauth")

public class OAuthController {

    @Value("${app.domain:reportv3.iretailer.net}")
    private String domain;


    private AuthRequestFactory factory;

    public AuthRequestFactory getFactory() {
        if (factory == null) {
            factory = SpringUtils.getBean(AuthRequestFactory.class);
        }
        return factory;
    }

    @GetMapping
    public List<String> list() {
        return getFactory().oauthList();
    }

    @SneakyThrows
    @GetMapping("/{type}/login")
    public void login(@PathVariable String type, HttpServletResponse response) {
        AuthRequest authRequest = getFactory().get(type);
        response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
    }

    @SneakyThrows
    @SuppressWarnings("unchecked")
    @RequestMapping("/{type}/callback")
    public void login(@PathVariable String type, AuthCallback callback, HttpServletResponse response) {
        AuthRequest authRequest = getFactory().get(type);
        AuthResponse<AuthUser> authResponse = authRequest.login(callback);
        log.info("【response 第三方登录认证回调 {}】\n{}", type, JSONUtil.toJsonStr(authResponse));
        RMap result;
        if (authResponse.getCode() == 2000) {
            try {
                AuthUser data = authResponse.getData();
                Subject subject = SecurityUtils.getSubject();
                WxenAuthToken token = new WxenAuthToken(data.getUuid());
                subject.login(token);
                result = RMap.ok();
                result.put("data", "/briefs");
                result.put("userInfo", subject.getPrincipal());
                result.put("toke", subject.getSession().getId());
            } catch (LockedAccountException e) {
                result = RMap.error(InternationalMessage.LOGIN_FAILED_THE_USER_IS_FROZEN.getByLanguage(SecurityUserUtil.defaultLanguage()));
            } catch (AuthenticationException e) {
                result = RMap.error(InternationalMessage.USER_NAME_OR_PASSWORD_ERROR.getByLanguage(SecurityUserUtil.defaultLanguage()));
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            log.error("【第三方登录认证失败】- {}", authResponse.getMsg());
        }
        response.sendRedirect(String.format("http://%s", domain));
    }

}
